﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace SharedLib.CrossCuttingFramework
{
    public abstract class AppFacade
    {
        private IUnityContainer _diContainer;
        /// <summary>
        /// DI Container from Unity
        /// </summary>
        public IUnityContainer DIContainer
        {
            get { return _diContainer; }
        }

        private LogWriter _logWriter;
        /// <summary>
        /// Log Writter from Microsoft Enterprise Library
        /// </summary>
        public LogWriter LogWriter
        {
            get
            {
                if (_logWriter == null) _logWriter = DIContainer.Resolve<LogWriter>();
                return _logWriter;
            }
        }

        private ExceptionManager _exceptionManager;
        /// <summary>
        /// Exception Manager from Microsoft Enterprise Library
        /// </summary>
        public ExceptionManager ExceptionManager
        {
            get
            {
                if (_exceptionManager == null) _exceptionManager = DIContainer.Resolve<ExceptionManager>();
                return _exceptionManager;
            }
        }

        private ValidatorFactory _valFactory;
        /// <summary>
        /// Validator Factory from Microsoft Enterprise Library
        /// </summary>
        public ValidatorFactory ValidatorFactory
        {
            get
            {
                if (_valFactory == null) _valFactory = DIContainer.Resolve<ValidatorFactory>();
                return _valFactory;
            }
        }

        public virtual void Initialize()
        {
            _diContainer = new UnityContainer().LoadConfiguration();
            _diContainer.AddNewExtension<EnterpriseLibraryCoreExtension>();

            LogWriter.Write("Enterprise Library Initiated");

            //Load from custom file
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename = "Unity.config" };
            System.Configuration.Configuration configuration =
                ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            UnityConfigurationSection unitySection = (UnityConfigurationSection)configuration.GetSection("unity");

            _diContainer.LoadConfiguration(unitySection);
            LogWriter.Write("Custom Unity Settings Initiated");

            LogWriter.Write("App Facade Initiated");
        }

        protected void LoadPluginsToDIContainer(PluginManager manager)
        {
            //Load plugin classes to DI container
            foreach (Type interfaceType in manager.RegisteredClasses.Keys)
            {
                IDictionary<string, Type> classDict = manager.RegisteredClasses[interfaceType];
                foreach (string name in classDict.Keys)
                {
                    Type classType = classDict[name];
                    DIContainer.RegisterType(interfaceType, classType, name);
                }
            }
        }
    }
}
